/**
 * 
 */
package pt.inescid.components.console;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Hashtable;
import java.util.Map;

import pt.inescid.components.commons.FrontEnd;
import pt.inescid.components.console.commands.Command;
import pt.inescid.components.console.commands.CommandException;
import pt.inescid.components.console.commands.HelpCommand;
import pt.inescid.components.console.commands.QuitCommand;
import pt.inescid.components.console.commands.SetMaxStorageCommand;
import pt.inescid.components.console.commands.SetMinRatioCommand;
import pt.inescid.components.console.commands.SetNMaxTasksCachedCommand;
import pt.inescid.components.console.commands.SetNTasksInProgressCommand;
import pt.inescid.components.console.commands.SetRatioCommand;
import pt.inescid.components.console.commands.SetWorkTimeCommand;
import pt.inescid.components.console.commands.ShowMaxStorageCommand;
import pt.inescid.components.console.commands.ShowNMaxTasksCachedCommand;
import pt.inescid.components.console.commands.ShowNTasksInProgressCommand;
import pt.inescid.components.console.commands.ShowNeighborsCommand;
import pt.inescid.components.console.commands.ShowMinRatioCommand;
import pt.inescid.components.console.commands.ShowRatioCommand;
import pt.inescid.components.console.commands.ShowResourcesCommand;
import pt.inescid.components.console.commands.ShowWorkTimeCommand;
import pt.inescid.components.console.commands.SubmitJobCommand;
import pt.inescid.components.console.commands.SubmitJobSample2Command;
import pt.inescid.components.console.commands.SubmitJobSampleCommand;
import pt.inescid.core.GridP2P;



/**
 * @author Sergio Esteves (sesteves at gsd.inesc-id.pt)
 *
 */
public class Console extends FrontEnd implements Runnable {

	private Map<String,Command> commands = new Hashtable<String,Command>();
	
	public Console(GridP2P gridP2P) {
		super(gridP2P);
	}	
	
	@Override
	public void init() {
		// to add a new command just add the respective class to this array
		Command cmd[] = {new SubmitJobCommand(this), new SubmitJobSampleCommand(this), 
				new HelpCommand(this), new QuitCommand(this), new ShowNeighborsCommand(this),
				new ShowResourcesCommand(this), new ShowWorkTimeCommand(this), 
				new SetWorkTimeCommand(this), new ShowMaxStorageCommand(this),
				new SetMaxStorageCommand(this), new ShowMinRatioCommand(this),
				new SetMinRatioCommand(this), new ShowRatioCommand(this),
				new SetRatioCommand(this), new ShowNTasksInProgressCommand(this),
				new SetNTasksInProgressCommand(this), new SubmitJobSample2Command(this),
				new ShowNMaxTasksCachedCommand(this), new SetNMaxTasksCachedCommand(this)
				};
		for(Command c : cmd)
			commands.put(c.getCmdName(), c);
		new Thread(this).start();
	}
	
	public void run() {		
    	String line;
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        System.err.println("-----GridP2P terminal-----" +
        		"\nType '" + HelpCommand.CMD_NAME + "' for a list of available commands");
        while(true) {
        	System.err.print("> ");
	        	
    	    try {
	        	line = in.readLine();
		    } catch (IOException e) {
		    	throw new RuntimeException(e);
		    }		

    		String[] args = line.split("\\s");		
    		if(args.length < 1) 
    			continue;
    		String str = args[0];
    		
    		// validate commands
    		if(commands.containsKey(str)) {
    			try {
    				if(HelpCommand.CMD_NAME.equals(str)) {
    					for(Command c : commands.values())
    						if(c instanceof HelpCommand) 
    							continue;
    						else
    							System.out.println(c.synopsis());
    				}
    				commands.get(str).execute(args);
    			} catch (CommandException e) {
    				System.err.println(e.getMessage() 
    						+ " (type '" +HelpCommand.CMD_NAME+ "' for help)");
    			}
    		} else {
    			System.err.println("Invalid Command!");
    			continue;
    		}
        }
	}
	
	@Override
	public void writeln(String str) {
		System.out.println(str);
	}
	
	public GridP2P getGridP2P() {
		return gridP2P;
	}
}
